#!/usr/bin/python


class Solution(object):

  def __init__(self, doctors, schedule, assignment):
    self.doctors = doctors
    self.schedule = schedule
    self.assignment = assignment

  def FormatSolutionAsMap(self):
    solution_list = [[] for _ in range(len(self.assignment))]
    total_shifts = [0] * len(self.doctors)
    consecutive_days = [0] * len(self.doctors)
    max_consecutive_days = [0] * len(self.doctors)
    day_shifts = [0] * len(self.doctors)
    night_shifts = [0] * len(self.doctors)
    for i in range(len(self.assignment)):
      value = self.assignment[i]
      if self.schedule.IsDay(i):
        all_day_value = value
        if i + 1 < len(self.assignment):
          all_day_value |= self.assignment[i + 1]
        for j in range(len(self.doctors)):
          if all_day_value & (1 << j):
            consecutive_days[j] += 1
          else:
            max_consecutive_days[j] = max(
                max_consecutive_days[j], consecutive_days[j])
            consecutive_days[j] = 0
      for j, doc in enumerate(self.doctors):
        if value & (1 << j):
          solution_list[i].append(self.doctors[j])
          total_shifts[j] += 1
          if self.schedule.IsDay(i):
            day_shifts[j] += 1
          else:
            night_shifts[j] += 1
    for j in range(len(self.doctors)):
      max_consecutive_days[j] = max(
          max_consecutive_days[j], consecutive_days[j])
    return {"solution": solution_list,
        "total_shifts": total_shifts,
        "consecutive_days": consecutive_days,
        "day_shifts": day_shifts,
        "night_shifts": night_shifts}

  def FormatSolutionAsString(self):
    lines = []
    total_shifts = [0] * len(self.doctors)
    consecutive_days = [0] * len(self.doctors)
    max_consecutive_days = [0] * len(self.doctors)
    day_shifts = [0] * len(self.doctors)
    night_shifts = [0] * len(self.doctors)
    for i in range(len(self.assignment)):
      value = self.assignment[i]
      if self.schedule.IsDay(i):
        lines.append("")
        lines.append("%d:" % self.schedule.DayForShiftNumber(i))
        lines.append("Day")
        all_day_value = value
        if i + 1 < len(self.assignment):
          all_day_value |= self.assignment[i + 1]
        for j in range(len(self.doctors)):
          if all_day_value & (1 << j):
            consecutive_days[j] += 1
          else:
            max_consecutive_days[j] = max(
                max_consecutive_days[j], consecutive_days[j])
            consecutive_days[j] = 0
      else:
        lines.append("Night")
      for j, doc in enumerate(self.doctors):
        if value & (1 << j):
          lines.append("  %s" % doc.name)
          total_shifts[j] += 1
          if self.schedule.IsDay(i):
            day_shifts[j] += 1
          else:
            night_shifts[j] += 1
    for j in range(len(self.doctors)):
      max_consecutive_days[j] = max(
          max_consecutive_days[j], consecutive_days[j])
    lines.append("")
    lines.append("Totals")
    for doc, total, day, night in (
        zip(self.doctors, total_shifts, day_shifts, night_shifts)):
      lines.append("%s: %d (%d day, %d night)" % (doc.name, total, day, night))
    lines.append("")
    lines.append("Max consecutive")
    for doc, d in zip(self.doctors, max_consecutive_days):
      lines.append("%s: %d" % (doc.name, d))
    return "\n".join(lines)
